package com.qf.config;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.qf.exception.CaptchaException;
import org.springframework.http.MediaType;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * 验证码过滤器
 *
 * @USER: Administrator
 * @DATE: 2025/8/31 上午9:18
 * @VERSION: 1.0.0
 */
public class CaptchaFilter extends OncePerRequestFilter {

    /**
     * 登录请求处理URL（与Security配置中的loginProcessingUrl一致）
      */

    private final String loginProcessingUrl;

    /**
     * 验证码验证失败处理器（与Security配置中的authenticationFailureHandler一致）
     */
    private final AuthenticationFailureHandler failureHandler;

    public CaptchaFilter(String loginProcessingUrl, AuthenticationFailureHandler failureHandler) {
        this.loginProcessingUrl = loginProcessingUrl;
        this.failureHandler = failureHandler;
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        // 只拦截登录请求
        if (loginProcessingUrl.equals(request.getRequestURI())
                && "POST".equalsIgnoreCase(request.getMethod())) {

            try {
                // 验证验证码
                validateCaptcha(request);
            } catch (AuthenticationException e) {
                // 验证码验证失败，调用失败处理器
                failureHandler.onAuthenticationFailure(request, response, e);
                return; // 终止过滤器链
            } catch (CaptchaException e) {
                // 验证码错误：返回 JSON 响应
                response.setContentType(MediaType.APPLICATION_JSON_VALUE);
                response.setCharacterEncoding("UTF-8");

                // 构建 JSON 响应体
                Map<String, Object> result = new HashMap<>();
                result.put("success", false);
                result.put("message", e.getMessage()); // 错误消息（如"验证码错误"）

                // 转换为 JSON 并写入响应
                ObjectMapper objectMapper = new ObjectMapper();
                response.getWriter().write(objectMapper.writeValueAsString(result));
                return; // 终止过滤器链
            }
        }

        // 验证码验证通过或非登录请求，继续执行后续过滤器
        filterChain.doFilter(request, response);
    }

    /**
     * 验证验证码是否正确
     */
    private void validateCaptcha(HttpServletRequest request) {
        // 获取用户输入的验证码
        String inputCaptcha = request.getParameter("captcha");
        // 获取Session中存储的验证码
        HttpSession session = request.getSession();
        String sessionCaptcha = (String) session.getAttribute("SESSION_CAPTCHA");

        // 验证逻辑
        if (inputCaptcha == null || inputCaptcha.trim().isEmpty()) {
            String msg = "验证码不能为空";
            throw new CaptchaException(msg);
        }
        if (sessionCaptcha == null) {
            String msg = "验证码已过期，请刷新重试";
            throw new CaptchaException(msg);
        }
        if (!inputCaptcha.equalsIgnoreCase(sessionCaptcha)) {
            String msg = "验证码错误，请重新输入";
            throw new CaptchaException(msg);
        }

        // 验证通过后移除Session中的验证码，防止重复使用
        session.removeAttribute("SESSION_CAPTCHA");
    }

}
